Working with Cron Jobs
Cron jobs are a standard method of scheduling tasks to run on your server. Cron is a service running in the background that will execute commands (jobs) at a specified time, or at a regular interval. Jobs and their schedules are defined in a configuration file called a crontab.
ℹ️ If you have cPanel, cron jobs can be managed directly in your control panel without directly modifying a crontab. See cPanel's Cron Jobs Feature for more information.
Configuration
Cron jobs are stored in a crontab file by username. These files are
stored in /var/spool/cron/crontabs
or /var/spool/cron/
. These files
should not be edited directly. The crontab
command should always
be used to make changes.
-
Your crontab can be edited using the following command:
$ crontab -e
That command will open the crontab in a text editor where you can make the necessary changes. Saving the changes, and closing the file will install the new crontab.
-
The following command will allow you to view your crontab without making changes:
$ crontab -l
-
The following command with remove your crontab entirely:
$ crontab -r
⚠️ All of the above commands affects only the crontab for the user you are logged in as. That is, if you are logged in as
myuser
, you would only affect the crontab of myuser. If you are logged in as a privileged user (such asroot
), you can affect other users using the-u
option. For example, the following command would edit the crontab formyuser
:$ crontab -u myuser -e
The
-u
can be supplied with any of the other options used above.
Syntax
A crontab file tells the Cron daemon what commands to run, and when to run them. It has three different kinds of lines: cron command, environment setting, and comment. Blank lines, leading spaces, and tabs are ignored.
Comments
Any line whose first non-whitespace character is a pound-sign (#) will be considered a comment. Inline comments are not allowed. Comments are not processed by the Cron daemon.
Environment Setting
Environment setting is in the form of:
name = value
Whitespace around the equal sign (=) are optional, and everything to the right of the equal sign is considered part of the value. The value can be quoted (with single or double quotes) to preserve leading or trailing spaces. Many environment variables are assigned a default value:
SHELL
is set to/bin/sh
.HOME
andLOGNAME
are set by/etc/passwd
.
SHELL
and HOME
can be overridden by environment settings,
but LOGNAME
can not.
The MAILTO
variable is checked to see if mail needs to be sent. By
default, mail is sent to the owner of the crontab. Mail can be sent to
another email address by assigning it to MAILTO
. If you don't want
Cron to send mail, assign MAILTO
to the empty string (MAILTO=""
).
The MAILTO
variable will only affect where emails are sent for
commands that come after the line it is assigned. If you want to change
all the email address of all commands, you would need to
assign MAILTO
at the top of the file. If you want to change the
email address for a single command, you would set MAILTO
directly
above the command, and then set MAILTO
back to its previous value
before the next command.
Cron Commands
A cron command has six fields: five date and time fields, and a command field. The Cron daemon checks the schedule of each job every minute. A job is run whenever the time, and date matches the current time and date.
A full cron command will look something like this:
0 0 * * * /path/to/command
Scheduling
The five date and time fields are minute, hour, day of the month, month, and day of the week respectively:
┌───────────── minute
│ ┌───────────── hour
│ │ ┌───────────── day of the month
│ │ │ ┌───────────── month
│ │ │ │ ┌───────────── day of the week
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
* * * * *
ℹ️ Above diagram courtesy of Wikipedia.
Field | Accepted Values |
---|---|
minute | 0-59 |
hour | 0-23 |
day of the month | 1-31 |
month | 1-12 or names (see below) |
day of the week | 0-7 (Sunday is 0 or 7) or names |
Cron jobs are run whenever the minute , hour , and month fields match the current time, and when at least one of the day of the month , or day of the year fields matches.Names for days of the week, or months are the first three letters of a day or month (e.g Mon for Monday, Oct for October).
Crons scheduled to run at times that can be "skipped" may result in jobs not running when you expect them to. A cron scheduled to run on the 31st of each month would only run during January, March, May, July, August, October, and November. If a daylight savings time change occurs, a cron job scheduled to run at a time that is skipped, or occurs twice will be skipped or be executed twice respectively.
All fields may contain an asterisk (*) which stands for any value.
Ranges are allowed, and are written as two numbers separated by a hyphen (-). Ranges are inclusive.
Lists are allowed, and are numbers or ranges separated by commas
e.g. 1,3,5,7
, or 0-7,16-23
.
Step values may be used with ranges. A step value is written as a range
followed by a forward slash (/), and a number. The number will tell the
Cron daemon how many times it should skip that job before running it
again. The value 0-23/2
in the hour field tells Cron to execute
the command every other hour. Step values may be used with asterisks as
well so */2
will also tell Cron to run a command every other hour.
Commands
The last field of a cron command is the command to be run. Specifically,
everything after the day of the week field until a newline or '%'
character is considered to be part of the command, and will be executed
by the shell set in the SHELL
environment variable (/bin/sh
by
default).
All '%' characters in a command are converted to newline characters. A
literal '%' must be escaped with a preceding backslash (\) e.g. \%
.
No other characters need to be escaped in a command.
Extensions
There are a handful of special time shorthand that may be used instead of the five date and time fields.
Shorthand | Value |
---|---|
@reboot | Runs once after a reboot. |
@yearly or @annually | Run once a year (0 0 1 1 * ). |
@monthly | Run once a month (0 0 1 * * ). |
@weekly | Run once a week (0 0 * * 0 ). |
@daily | Run once a day (0 0 * * * ). |
@hourly | Run once an hour (0 * * * * ). |
Examples
-
A command that runs every minute:
* * * * * /path/to/command
-
A command that runs every 5th minute on the hour (e.g. 1:05, 2:05, 3:05 etc.):
5 * * * * /path/to/command
-
A command that runs every 10 minutes:
0,10,20,30,40,50 * * * * /path/to/command
-
A command that runs every 6 minutes:
*/6 * * * * /path/to/command
-
A command that runs every Monday at 8:00 AM:
0 8 * * 1 /path/to/command
-
A command that runs the first Tuesday of every month at 5:30 PM:
30 17 1-7 * 2 /path/to/command
Output
As previously mentioned, the Cron daemon will email the output of the
command to user's email address, or the address set by MAILTO
whenever
a cron job is executed. This can become a problem however if a command
is run frequently. Stopping the emails is an option by
setting MAILTO=""
, but you will then lose the output of the commands.
Shell redirection can be used to have the output written to a file
instead of being sent as an email.
-
The following command will write to a log file every hour:
0 * * * * echo "Hourly message." > message.log
-
The command that gets executed is
echo "Hourly message."
. The remaining part of the line,> message.log
, redirects the output to a file namedmessage.log
. It's important to note that this will replace whatever is inmessage.log
withHourly message
. The>>
operator will append to the end of a file instead of overwriting it:0 * * * * echo "Hourly message." >> message.log
-
If this cron job ran 3 times, the contents of
message.log
would look like this:Hourly message.
Hourly message.
Hourly message. -
If you don't care about the normal output of a cron job, and only want to be notified when it encountered an error, you can redirect the output to
/dev/null
.0 * * * * /path/to/my/script > /dev/null
/dev/null
is a special device file in Linux (and other Unix-like operating systems) that is used when discard output. Anything that is written to this file just gets thrown away by the system. -
Redirection can be used to prevent emails from being sent as well by sending both normal output and error messages to
/dev/null
instead of settingMAILTO=""
.0 * * * * /path/to/my/script 2>&1 > /dev/null
2>&1
in short says to treat error messages like normal output. So2>&1 > /dev/null
can be read as "treat error messages like normal output, and throw away normal output".